package com.yimu.ymblog.jwt.handler;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yimu.ymblog.common.domain.dos.UserDO;
import com.yimu.ymblog.common.domain.dos.UserInfoDO;
import com.yimu.ymblog.common.domain.mapper.UserInfoMapper;
import com.yimu.ymblog.common.domain.mapper.UserMapper;
import com.yimu.ymblog.common.utils.IpUtil;
import com.yimu.ymblog.common.utils.Response;
import com.yimu.ymblog.jwt.model.LoginRspVO;
import com.yimu.ymblog.jwt.utils.JwtTokenHelper;
import com.yimu.ymblog.jwt.utils.ResultUtil;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;

/**
 * 自定义认证成功处理器
 */
@Component
@Slf4j
public class RestAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    @Autowired
    private JwtTokenHelper jwtTokenHelper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private UserMapper userMapper;


    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        // 从 authentication 对象中获取用户的 UserDetails 实例，这里是获取用户的用户名
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();

        // 通过用户名生成 Token
        String username = userDetails.getUsername();
        String token = jwtTokenHelper.generateToken(username);

        // 返回 Token
        LoginRspVO loginRspVO = LoginRspVO.builder().token(token).build();

        LambdaQueryWrapper<UserDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserDO::getUsername, username);
        // 查询当前用户id
        UserDO userDO = userMapper.selectOne(wrapper);
        Long userId = userDO.getId();

        // 登录校验通过生成Token后，还要修改一下用户信息表
        log.info("用户 {} 登录成功", username);

        // 设置最后登录时间 ip地址 ip来源 登录方式 登录系统 浏览器
        String ip = IpUtil.getIp();
        String cityInfo = IpUtil.getCityInfo(ip);
        UserAgent userAgent = IpUtil.getUserAgent(IpUtil.getRequest());
        String os = userAgent.getOperatingSystem().getName();
        String browser = userAgent.getBrowser().getName();
        UserInfoDO userInfoDO = UserInfoDO.builder()
                .ipAddress(ip)
                .ipSource(cityInfo)
                .os(os)
                .browser(browser)
                .lastLoginTime(LocalDateTime.now())
                .build();
        LambdaUpdateWrapper<UserInfoDO> updateWrapper = new LambdaUpdateWrapper<>();
        userInfoMapper.update(userInfoDO, updateWrapper.eq(UserInfoDO::getUserId, userId));


        ResultUtil.ok(response, Response.success(loginRspVO));
    }
}